package jroguelike.main.ai;

import jroguelike.main.ArtificialIntelligence;
import jroguelike.main.Creature;
import jroguelike.main.RLMap;

import java.util.LinkedList;

/**
 * Created by IntelliJ IDEA.
 * User: aimozg
 * Date: 06.08.11
 * Time: 15:14
 */
public class BeastAi extends AbstractAi {

	public enum Mode {
		WANDERING, CHASING;
	}

	private Mode mode = Mode.WANDERING;
	private Creature target;
	private int targetXy;

	private boolean meHostileTo(Creature other) {
		// TODO check factions
		return true;
	}

	@Override
	protected void cloneTo(ArtificialIntelligence other) {
		super.cloneTo(other);
		BeastAi xother = (BeastAi) other;
		xother.mode = mode;
		xother.target = target;
		xother.targetXy = targetXy;
	}

	@Override
	public void perform() {
		RLMap map = me.map();
		RLMap.FOV fov = map.genFOV(me.x(), me.y(), me.sight());
		while (true) {
			switch (mode) {
				case WANDERING: {
					LinkedList<Creature> targets = new LinkedList<>();
					for (Creature creature : map.creatureList()) {
						if (fov.visible(creature.x(), creature.y()) && creature != me && meHostileTo(creature)) {
							targets.add(creature);
						}
					}
					if (targets.isEmpty()) {
						aiWander();
					} else {
						mode = Mode.CHASING;
						target = targets.pop();
						int range = map.range(me, target);
						// select closest as a target and chase it
						for (Creature creature : targets) {
							int range2 = map.range(me, creature);
							if (range2 < range) {
								range = range2;
								target = creature;
							}
						}
						targetXy = target.xy();
						continue;
					}

				}
				break;
				case CHASING: {
					if (target.isDead() || target.map() != map) {
						// TODO what to do if different map?
						mode = Mode.WANDERING;
						continue;
					} else if (!fov.visible(target.xy())) {
						// move to last known position
						if (!aiMoveTo(targetXy)) {
							mode = Mode.WANDERING;
							continue;
						}
					} else {
						targetXy = target.xy();
						if (map.range(targetXy, me.xy()) == 1) {
							aiMeleeAttack(target);
						} else {
							aiMoveTo(targetXy);
						}
					}
				}
				break;
			}
			break;
		}
	}

	@Override
	public ArtificialIntelligence makeClone(Creature newMe) {
		BeastAi beastAi = new BeastAi();
		cloneTo(beastAi);
		return beastAi.attach(newMe);
	}
}
